/*
 * @Description: 生成 vue useForm
 * @Author: DHL
 * @Date: 2022-01-30 14:20:12
 * @LastEditors: DHL
 * @LastEditTime: 2023-09-21 15:46:18
 */

import { firstToUpperCase, firstToLowerCase, getVueDefaultValue } from '../../utils/codeGenUtils'

export function createUseForm(codeGenConfig: any) {
  const classNameFirstToUpperCase = firstToUpperCase(codeGenConfig.className)
  const classNameFirstToLowerCase = firstToLowerCase(codeGenConfig.className)
  const apiPath = codeGenConfig.apiPath

  return `
/*
 * @Description: ${codeGenConfig.genName}
 * @Author: ${codeGenConfig.genAuthor}
 * @Date: ${codeGenConfig.createData}
 * @LastEditors: ${codeGenConfig.genAuthor}
 * @LastEditTime: ${codeGenConfig.createData}
 */

import { defineComponent, computed, reactive, ref } from 'vue'
import { log } from '@/utils/logUtils'
import { ElMessage } from 'element-plus'
import { cloneDeep, assign } from 'lodash-es'
import { isEmpty } from '@/utils/isUtils'
import { ${classNameFirstToUpperCase}Model } from '@/api/${apiPath}/model/${classNameFirstToLowerCase}Model'
import { api${classNameFirstToUpperCase}GetById, api${classNameFirstToUpperCase}Save, api${classNameFirstToUpperCase}UpdateById } from '@/api/${apiPath}/${classNameFirstToLowerCase}'

export default defineComponent({
  name: '${classNameFirstToUpperCase}Form',
  emits: ['refreshTableData'],
  setup(props, { emit, expose }) {
    //////////////////////////////////////////////////
    // 属性
    //////////////////////////////////////////////////
    const dbFormRef = ref()
    const loading = ref(true)

    /**
     * 表单操作标记
     */
    const action = ref('add')

    /**
     * 显示弹框
     */
    const visible = ref(false)

    /**
     * 标题
     */
    const title = computed(() => {
      const title = {
        add: '新增',
        edit: '编辑',
        view: '查看'
      }
      return title[action.value]
    })

    /**
     * 公共
     */
    const state = reactive({ })

    //////////////////////////////////////////////////
    // 表单
    //////////////////////////////////////////////////

    const defaultForm = {
      ${getField(codeGenConfig.optionsJson.columns)}
    }

    let dbForm = reactive<${classNameFirstToUpperCase}Model>(cloneDeep(defaultForm))

    //////////////////////////////////////////////////
    // 表单验证规则
    //////////////////////////////////////////////////

    /**
     * 表单验证规则
     */
    const rules = reactive({
      ${getRules(codeGenConfig.optionsJson.columns)}
    })

    //////////////////////////////////////////////////
    // 函数
    //////////////////////////////////////////////////

    /**
     * 打开弹框
     */
    function handleOpen(actionParam: string, rowParam?: ${classNameFirstToUpperCase}Model) {
      visible.value = true
      loading.value = false
      action.value = actionParam
      if (['edit', 'view'].includes(actionParam) && rowParam) {
        // assign(dbForm, cloneDeep(rowParam))
        handleSearchById(rowParam.id)
      }
    }

    /**
     * 关闭弹框
     */
    function handleClose() {
      assign(dbForm, cloneDeep(defaultForm))
      visible.value = false
    }

    /**
     * 根据主键查询详情
     * @param id 主键
     */
    function handleSearchById(id = '') {
      if (isEmpty(id)) {
        return
      }
      loading.value = true
      api${classNameFirstToUpperCase}GetById(id)
        .then((result) => {
          if (result?.success) {
            assign(dbForm, result.data)
          } else {
            ElMessage.error(result?.message)
          }
        })
        .catch(() => {})
        .finally(() => {
          loading.value = false
        })
    }

    /**
     * 提交表单
     */
    function handleSubmit(isContinue: boolean) {
      dbFormRef.value.validate((valid: boolean) => {
        if (valid) {
          if (action.value === 'add') {
            addFun(isContinue)
          } else {
            editFun()
          }
        } else {
          log.warn('${codeGenConfig.genName}', '表单校验失败')
        }
      })
    }

    /**
     * 新增
     * @param isContinue 是否新增并继续
     */
    function addFun(isContinue: boolean) {
      loading.value = true
      api${classNameFirstToUpperCase}Save(dbForm)
        .then((result) => {
          if (result?.success) {
            handleReset(!isContinue)
            ElMessage.success(result.message)
          } else {
            ElMessage.error(result?.message)
          }
        })
        .catch(() => {})
        .finally(() => {
          loading.value = false
        })
    }

    /**
     * 编辑
     * @returns
     */
    function editFun() {
      loading.value = true
      api${classNameFirstToUpperCase}UpdateById(dbForm)
        .then((result) => {
          if (result?.success) {
            handleReset(true)
            ElMessage.success(result.message)
          } else {
            ElMessage.error(result?.message)
          }
        })
        .catch(() => {})
        .finally(() => {
          loading.value = false
        })
    }

    /**
     * 重置表单
     * @param isClosed 是否关闭弹框
     */
    function handleReset(isClosed: boolean) {
      assign(dbForm, cloneDeep(defaultForm))
      if (isClosed) {
        emit('refreshTableData')
        visible.value = false
      }
    }

    /**
     * 暴露函数
     */
    expose({ handleOpen })

    return {
      loading,
      visible,
      action,
      title,
      state,
      dbFormRef,
      dbForm,
      rules,
      handleOpen,
      handleClose,
      handleSubmit,
      handleReset
    }
  }
})
`
}

/**
 * 获取字段
 * @param columns
 */
function getField(columns: any) {
  let field: Array<string> = []

  let fieldArray: any[] = []

  columns.forEach((item: any) => {
    if (item.form) {
      fieldArray.push(item)
    }
  })
  for (let i = 0; i < fieldArray.length; i++) {
    const item = fieldArray[i]

    if (i === fieldArray.length - 1) {
      field.push(`${item.javaField}: ${getVueDefaultValue(item)}  // ${item.javaComment}`)
    } else {
      field.push(`${item.javaField}: ${getVueDefaultValue(item)},  // ${item.javaComment}
      `)
    }
  }

  return field.join('')
}

/**
 * 获取表单验证
 * @param columns
 */
function getRules(columns: any) {
  let field: Array<string> = []

  let fieldArray: any[] = []

  columns.forEach((item: any) => {
    if (item.form) {
      fieldArray.push(item)
    }
  })

  for (let i = 0; i < fieldArray.length; i++) {
    const item = fieldArray[i]

    if (i === fieldArray.length - 1) {
      field.push(`${getRulesItem(item)}`)
    } else {
      if (item.required) {
        field.push(`${getRulesItem(item)},
      `)
      }
    }
  }

  return field.join('')
}

function getRulesItem(item: any) {
  let rtn = ''

  let errorMsg = ''

  switch (item.componentType) {
    case 'select':
      errorMsg = '请选择'
      break
    case 'radio':
      errorMsg = '请选择'
      break
    case 'checkbox':
      errorMsg = '请选择'
      break
    case 'datePicker':
      errorMsg = '请选择'
      break
    case 'dateTimePicker':
      errorMsg = '请选择'
      break
    case 'timePicker':
      errorMsg = '请选择'
      break
    case 'timeSelect':
      errorMsg = '请选择'
      break
    case 'switch':
      errorMsg = '请选择'
      break
    case 'upload':
      errorMsg = '请上传'
      break
    case 'dataDic':
      errorMsg = '请选择'
      break
    default:
      errorMsg = '请输入'
      break
  }

  errorMsg += item.javaComment

  let rules: Array<string> = []
  if (item.required) {
    rules.push(`  {
          required: true,
          message: '${errorMsg}',
          trigger: 'blur'
        }`)
  }

  if (item.charMaxLength) {
    rules.push(`  {
          max: ${item.charMaxLength},
          message: '最多可输入${item.charMaxLength}个字符',
          trigger: 'blur'
        }`)
  }

  rtn = `${item.javaField}: [
      ${rules.join(',')}
      ]`

  return rtn
}
